<#include "/includes/vars.inc"> 
<@pp.dropOutputFile />
<@pp.changeOutputFile name="${javaDir}${packageDir}/web/util/JsfUtil.java" />

package ${project.@rootPackage}.web.util;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Collection;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.core.io.Resource;
import org.springframework.web.jsf.FacesContextUtils;

/**
 * JsfUtil class
 * <#if project.@author[0]??>@author ${project.@author}</#if>
 */
public class JsfUtil {

    /**
     * Close the current session
     */
    public static void closeSession() {
        FacesContext context = FacesContext.getCurrentInstance();
        Object session = context.getExternalContext().getSession(false);
        HttpSession httpSession = (HttpSession) session;
        httpSession.invalidate();
    }

    public static HttpServletRequest getRequest() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext ectx = ctx.getExternalContext();
        HttpServletRequest req = (HttpServletRequest) ectx.getRequest();
        return req;
    }

    /**
     * Return the absolut path of a relative path
     * @param path
     * @return absolut path
     */
    public static String getRealPath(String path) {
        return FacesContext.getCurrentInstance().getExternalContext().getRealPath(path);
    }

    /**
     * Add a error message to the specific component
     * @param id
     * @param msg description
     */
    public static void addErrorMessage(String id, String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
        FacesContext.getCurrentInstance().addMessage(id, facesMsg);
    }

    /**
     * Add a global warning message to the app
     * @param id
     * @param msg description
     */
    public static void addWarningMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN, msg, msg);
        FacesContext.getCurrentInstance().addMessage(null, facesMsg);
    }

    /**
     * Returns the instance of a managed bean
     * @param beanName
     * @return managed bean
     */
    
 
    /**
     * Añade un mensaje satisfactorio local al componente especificado por su id.
     * @param id componente
     * @param msg descripcion del mensaje
     */
    public static void addSuccessMessage(String id, String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
        FacesContext.getCurrentInstance().addMessage(id, facesMsg);
    }

    /**
     * Add a global error message to the app
     * @param id
     * @param msg description
     */
    public static void addErrorMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
        FacesContext.getCurrentInstance().addMessage(null, facesMsg);
    }

    /**
     * Add a global success message to the app
     * @param id
     * @param msg description
     */
    public static void addSuccessMessage(String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
        FacesContext.getCurrentInstance().addMessage(null, facesMsg);
    }

    /**
     * Redirect to a url inside the context of the app
     * @param url
     */
    public static void redirect(String url) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext ectx = ctx.getExternalContext();
        String newUrl = ectx.encodeActionURL(ctx.getApplication().getViewHandler().getActionURL(ctx, url));
        try {
            ectx.redirect(newUrl);
        } catch (IOException ex) {
            throw new FacesException(ex);
        }
    }

    /**
     * Redirect to a view of the app
     * @param view
     */
    public static void redirectToView(String view) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext ectx = ctx.getExternalContext();
        HttpServletRequest req = (HttpServletRequest) ectx.getRequest();
        try {
            ectx.redirect(req.getContextPath() + view);
        } catch (IOException ex) {
            throw new FacesException(ex);
        }
    }

    /**
     * Redirect to a url extern
     * @param url
     */
    public static void redirectToExternUrl(String url) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        ExternalContext ectx = ctx.getExternalContext();
        try {
            ectx.redirect(url);
        } catch (IOException ex) {
            throw new FacesException(ex);
        }
    }

    /**
     * @param entities item list
     * @param selectOne if is true select one is required
     * @return selectItem
     */
    public static SelectItem[] getSelectItems(Collection<?> entities, boolean selectOne) {
        int size = selectOne ? entities.size() + 1 : entities.size();
        SelectItem[] items = new SelectItem[size];
        int i = 0;
        if (selectOne) {
            items[0] = new SelectItem(null, "---");
            i++;
        }
        for (Object x : entities) {
            items[i++] = new SelectItem(x, x.toString());
        }
        return items;
    }
    
    /**
     * @param entities item list
     * @param selectOne if is true select one is required
     * @return selectItem
     */
    public static SelectItem[] getEnumItems(Collection<?> entities, boolean selectOne) {
        int size = selectOne ? entities.size() + 1 : entities.size();
        SelectItem[] items = new SelectItem[size];
        int i = 0;
        if (selectOne) {
            items[0] = new SelectItem("", "---");
            i++;
        }
        for (Object x : entities) {
            items[i++] = new SelectItem(x.toString(), x.toString());
        }
        return items;
    }

    /**
     * Returns the localized message from the i18n.Messages
     * @param key
     * @return mensaje
     */
    public static String getMessage(String key) {
        String res = "";
        try {
            res = ResourceBundle.getBundle("i18n.messages", getLocale()).getString(key);
        } catch (Exception e) {
             Logger.getAnonymousLogger().log(Level.WARNING,"'" + key + "' no encontrado en i18n.messages_" + getLocale());
        }
        return res;
    }
    
    
    /**
     * Format a number depending on the currency.
     * @param number
     */
    public static String numberToCurrency(Double number) {
        Double n = Math.round(number * Math.pow(10, 2)) / Math.pow(10, 2);
        //Util.logInfo("Language: "+getLocale().getLanguage() + " Country: "+getLocale().getCountry());
        if (getLocale().getLanguage().equals("es")) {
            return n + " €";
        } else if (getLocale().getLanguage().equals("en")) {
            if (getLocale().getCountry().equals("US")) {
                return "$" + n;
            } else {
                return "$" + n;
            }
        } else {
            return n + " €";
        }
    }
        
     /**
     * Format a date depending on the locale 
     * @param date
     * @return date formated
     */
    public static String formatDate(Date date) {
        Locale locale = getLocale();
        SimpleDateFormat df;
        if (locale.getLanguage().equals("es")) {
            df = new SimpleDateFormat("dd/MM/yyyy");
            return df.format(date);
        } else if (locale.getLanguage().equals("en")) {
            df = new SimpleDateFormat("MM/dd/yyyy");
            return df.format(date);
        } else {
            //throw new FacesException("Locale " + locale.getLanguage() + " no definido");
            df = new SimpleDateFormat("dd/MM/yyyy");
            return df.format(date);
        }
    }

    /**
     * Returns the localized message from a specific resource
     * @param key
     * @return mensaje
     */
    public static String getMsg(String resource, String key) {
        return ResourceBundle.getBundle(resource, getLocale()).getString(key);
    }

    /**
     * @return current instance of the locale 
     */
    public static Locale getLocale() {
        return FacesContext.getCurrentInstance().getViewRoot().getLocale();
    }

    /**
    * @return bean instance
    */
    public static Object getBean(String beanName) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        return FacesContextUtils.getWebApplicationContext(ctx).getBean(beanName); 
    }
    
    /**
    * @return resource
    */
    public static Resource getResource(String path) {
        FacesContext ctx = FacesContext.getCurrentInstance();
        return FacesContextUtils.getWebApplicationContext(ctx).getResource(path);
    }

    /**
    * @return request parameter
    */
    public static String getParameter(String key){
        return  FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
    }
}
